package it.unibo.refolding.pico.batch;

import it.unibo.refolding.pico.PicoDataAnalyser;
import it.unibo.refolding.pico.PicoUtil;
import it.unibo.refolding.pico.RetractionCurve;
import it.unibo.refolding.pico.RetractionPeak;

import java.io.IOException;
import java.io.Writer;
import java.util.Locale;

import com.google.common.collect.ImmutableList;

public class BatchUtil {

  static final String HOOKE_HEADER = "<?xml version=\"1.0\" ?>\n<playlist>\n<generics pointer=\"0\"/>\n";
  static final String HOOKE_FOOTER = "</playlist>\n";

  public static boolean writeIfNecessary(
    double clRangeStartM, double clRangeEndM, int wellSpacedAtEnd, int allowSkipped,
    RetractionCurve value, int iteration, Writer retractionFw) throws IOException {
    boolean written;
    if (wellSpacedAtEnd == 0
      || (!value.isEmpty() && PicoDataAnalyser.wellSpacedAtEnd(
        value.peakContourLengthsFromContactPointOnwards(iteration),
        clRangeStartM, clRangeEndM, allowSkipped) >= wellSpacedAtEnd)) {
      retractionFw.write(value.repr() + "\n");
      written = true;
    } else {
      written = false;
    }
    return written;
  }

  static void writePeakCsvEntry(int i, RetractionCurve value, int iteration, Writer retractionFw) throws IOException {
    Iterable<RetractionPeak> lastSegmentPeaks = value.isEmpty() ? ImmutableList.<RetractionPeak>of()
      : value.segment(iteration).peaks;
    for (RetractionPeak peak : lastSegmentPeaks) {
      // Starting from 1.
      retractionFw.write(value.path + ", " + (i + 1) + ", " + peak.contourLengthM * 1e9
        + ", " + peak.ruptureForceN * 1e12 + "\n");
    }
  }

  static String hookeElement(RetractionCurve a, int iteration) {
    String sb = PicoUtil.toNmPnNmNmString(a.contourLengthNonNegativeRuptureForceExtensionAndDistanceOfPeaksFromContactPointOnwards(iteration));
    return String.format(Locale.ROOT, "<element notes=\"[%s]\" path=\"%s\"/>", sb, a.path);
  }

  static boolean writeHookeElement(
    double clRangeStartM, double clRangeEndM, int wellSpacedAtEnd, int allowSkipped,
    RetractionCurve value, int iteration, Writer hookeFw) throws IOException {
    boolean written;
    if (!value.isEmpty()
      && PicoDataAnalyser.wellSpacedAtEnd(
        value.peakContourLengthsFromContactPointOnwards(iteration), clRangeStartM,
        clRangeEndM, allowSkipped) >= wellSpacedAtEnd) {
      hookeFw.write(hookeElement(value, iteration) + "\n");
      written = true;
    } else {
      written = false;
    }
    return written;
  }
}
